#include <stdio.h>
#include "cJSON.h"
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
/*char* stt_send_request(const char* token, const char* audio, size_t size)
{
    FILE* fp;
    //响应消息的地址
    char* response = NULL;
    //响应消息的长度
    size_t resplen = 0;
    //创建内存文件，当通过文件句柄写入数据时，会自动分配内存
    fp = open_memstream(&response, &resplen);
    if (fp == NULL) //打开文件失败，打印错误信息并退出
    {
        perror("open_memstream() failed");
        return NULL;
    }

    //初始化HTTP客户端
    CURL* curl = curl_easy_init();
    if (curl == NULL)
    {
        perror("curl_easy_init() failed");
        return NULL;
    }

    //拼接API地址和参数
    char* url = NULL;
    asprintf(&url, "http://vop.baidu.com/server_api?cuid=liuyu&token=%s&dev_pid=1537", token);

    //准备HTTP请求消息，设置API地址（URI）
    curl_easy_setopt(curl, CURLOPT_URL, url);
    //创建请求头链表
    struct curl_slist* headers = NULL;
    //向链表中增加头部字段
    headers = curl_slist_append(headers, "Content-Type: audio/pcm;rate=16000");
    //设置HTTP请求头部字段
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    //配置客户端，使用HTTP的POST方法发送请求消息
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    //配置需要通过POST请求消息发送给服务器的数据
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, audio);
    //指定发送数据的长度
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, size);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    //打印HTTP请求和响应消息头
    //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

    //发送HTTP请求消息，等待服务器的响应消息
    CURLcode error = curl_easy_perform(curl);
    if (error != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(error));
        curl_easy_cleanup(curl);
        fclose(fp);
        free(response);
        free(url);
        return NULL;
    }

    //释放HTTP客户端申请的资源
    curl_easy_cleanup(curl);

    //关闭内存文件
    fclose(fp);

    //释放asprintf申请的内存
    free(url);

    return response;
}*/
//使用APIKEY和SECERTKEY获得token
char * get_token(const char * api_key,const char * secret_key)
{
	//open file
	//FILE * fp=open_file("1.txt");
	//打开一个内存文件
	FILE *fp=NULL;
	
	//参数1：指针的指针     响应消息的地址
	//参数2：文件大小的指针 响应消息的长度
	char * response;
	size_t resplen;
	//创建内存文件，当通过文件句柄写入数据时,会自动分配内存
	fp=open_memstream(&response,&resplen);
	if(NULL==fp)
	{
		perror("open_memstream error");
		return NULL;
	}
	
	
	
	//创建http客户端
	
	// 1初始化
	//CURL * curl=curl_easy_init();
	///
	CURL * curl=curl_easy_init();
	char * uri=NULL;
	asprintf(&uri,"https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s",api_key,secret_key);//先分配一片内存,将数据放里面

	//2设置要访问的地址
	curl_easy_setopt(curl,CURLOPT_URL,uri);

	//3.将相应直接写入到该文件中
	curl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);
	//打印http请求和相应消息头
	//curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
	

	//3要访问的地址
	CURLcode error=curl_easy_perform(curl);
	if(error!=CURLE_OK)
	{
		perror("perform error\n");
		//fprintf(stderr,"");
		curl_easy_cleanup(curl);
		free(uri);
		free(response);
		fclose(fp);
		return NULL;
	}
	
	
	
	//4.清除curl
	curl_easy_cleanup(curl);
	free(uri);
	fclose(fp);
	//打印response
//	puts(response);
	
	//解析json字符串
	cJSON * json=cJSON_Parse(response);
	if(NULL==json)
	{
		const char * err_pos=cJSON_GetErrorPtr();
		if(NULL!=err_pos)
		{
			fprintf(stderr,"Error before:%s\n",err_pos);
		}
		return NULL;
	}
	
	
	
	cJSON * access_token= cJSON_GetObjectItemCaseSensitive(json, "access_token");
	

	if(!cJSON_IsString(access_token)){
	

		cJSON * err_des= cJSON_GetObjectItemCaseSensitive(json, "error_description");
		printf("%s",err_des->valuestring);
		return NULL;
	}
	

	//copy token str,free
	char * token=strdup(access_token->valuestring);

	//释放json数据结构占用的内存
	free(response);
	//
	cJSON_Delete(json);

	
	
	
	
	return token; 
	
	
	
}





//解析服务器响应报文
void stt_process_response(char * response);
void stt_process_response(char * response)
{

//解析json字符串
	cJSON * json=cJSON_Parse(response);


//	printf("json=%s\n",json->valuestring);
	if(NULL==json)
	{
		const char * err_pos=cJSON_GetErrorPtr();
		if(NULL!=err_pos)
		{
			fprintf(stderr,"Error before:%s\n",err_pos);
		}
		return ;
	}
	
	
	
	cJSON * err_no= cJSON_GetObjectItemCaseSensitive(json, "err_no");

//	printf("%d\n",err_no->valueint);	


	if(err_no->valueint!=0)
	{
		cJSON * err_msg= cJSON_GetObjectItemCaseSensitive(json, "err_msg");
		fprintf(stderr,"%s\n",err_msg->valuestring);
		return ;

	}

	cJSON * result= cJSON_GetObjectItemCaseSensitive(json, "result");

	//获取数组中的第一个元素
	cJSON * text=cJSON_GetArrayItem(result,0);

	printf("%s\n",text->valuestring);

	//释放json数据结构占用的内存
	free(response);
	//
	cJSON_Delete(json);

	
	
	
}





//读取音频数据到内存
size_t stt_load_file(char * filename,char ** paudio);
size_t stt_load_file(char * filename,char ** paudio)
{

	FILE * fp=fopen(filename,"r");
	if(NULL==fp)
	{
		perror("fopen error");
		return -1;
	}
	fseek(fp,0,SEEK_END);
	long size=ftell(fp);
	*paudio=malloc(size);
	if(NULL==*paudio)
	{
		perror("malloc error");
		return -1;
	}

	fseek(fp,0,SEEK_SET);

	fread(*paudio,1,size,fp);
	fclose(fp);
	return size;


}
 
//将语音数据发给云服务器,等待响应报文
char *stt_send_request( char * token,char * audio,size_t size);
char *stt_send_request(char * token,char * audio,size_t size)
{


	//1.初始化curl
	CURL * curl=curl_easy_init();
	
       if(NULL==curl)
       {
	       perror("init error");
	       return NULL;
       }	       
	
	//参数1：指针的指针     响应消息的地址
	//参数2：文件大小的指针 响应消息的长度
	char * response=NULL;
	size_t resplen;
	//创建内存文件，当通过文件句柄写入数据时,会自动分配内存
FILE *	fp=open_memstream(&response,&resplen);
	if(NULL==fp)
	{
		perror("open error");
		return NULL;
	}
	
        char * url=NULL;
	//拼接POST请求放的数据
	asprintf(&url,"http://vop.baidu.com/server_api?dev_pid=1537&cuid=gaomin&token=%s",token);


	//2.准备HTTP请求消息,设置API地址(URI)
	curl_easy_setopt(curl,CURLOPT_URL,url);
	//创建头部信息脸表
	//创建请求头链表
	struct curl_slist  *headers=NULL;
	//增加头部链表
	
	headers=curl_slist_append(headers,"Content-Type: audio/pcm;rate=16000");
	//设置http请求头部字段
	curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);

		
	//配置客户端,使用http的POST方法发送请求消息
	curl_easy_setopt(curl,CURLOPT_POST,1);
	
	//配置需要通过POST请求消息发送给服务器的数据
	curl_easy_setopt(curl,CURLOPT_POSTFIELDS,audio);
	//指定发送数据的长度
	curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,size);

	curl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);
	//打印HTTP请求和响应消息头
	curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
	CURLcode error=curl_easy_perform(curl);
	if(error!=CURLE_OK)
	{
		perror("perform error\n");
		//fprintf(stderr,"");
		curl_easy_cleanup(curl);
		pclose(fp);
		free(url);
		return NULL;
		
	}
	
	
	
	//4.清除curl
	curl_easy_cleanup(curl);

	
	free(url);	
	//关闭文件
	pclose(fp);

	return response;
}

int main(void)
{


	//指向音频数据的指针
	char * audio=NULL;
	//读取ＰＣＭ文件内容
	size_t size=stt_load_file("test.pcm",&audio);

        char* token = get_token("gG1oXkYhqC72KbsfKNawHZNv", "ijAXKgNwUaQZbbVXryZmef6DnouQ6EnS");
    if (NULL == token)
    {
        free(audio);
        return EXIT_FAILURE;
    }
/*	char * token=get_token("x1pEj9Y46p4MibGolQ0wcE0w","G7I0VLbCozYjDiuGWEejqnEMKo9bsgV7");

	printf("token=%s\n",token);	

	printf("----token=%s\n",token);
	if(-1==size)
	{
		return -1;
	}*/
	//将语音数据发给云服务器,等待响应报文
	//处理响应报文，将文本信息打印在屏幕上

	char * response=stt_send_request(token,audio,size);

	free(token);
	if(NULL==response)
	{
		return -1;
	}
	printf("response =%s --\n",response);
	stt_process_response(response);
	free(audio);

	






	return 0;
}
